package simpleparser

import (
	"fmt"
	"strings"
)

type TokenType int

type Token struct {
	Type  TokenType
	Value string
}

// 栈结果方便回溯
type TokenList struct {
	CurStep int
	Tokens  []Token
}

func (tl *TokenList) Push(token Token) {
	tl.Tokens = append(tl.Tokens, token)
}

func (tl *TokenList) Peek() *Token {
	if tl.CurStep >= len(tl.Tokens) {
		return nil
	}

	return &tl.Tokens[tl.CurStep]
}

func (tl *TokenList) Next() *Token {
	if tl.CurStep >= len(tl.Tokens) {
		return nil
	}

	token := tl.Tokens[tl.CurStep]
	tl.CurStep++
	return &token
}

func (tl *TokenList) Reset() {
	tl.CurStep = 0
}

func (tl *TokenList) getPosition() int {
	return tl.CurStep
}

func (tl *TokenList) setPosition(position int) {
	tl.CurStep = position
}

func (tl *TokenList) ResetStep(step int) bool {
	if tl.CurStep <= 0 {
		return false
	}

	tl.CurStep += step
	return true
}

// AstNode represents a node in the AST

type AstNodeType int

const (
	DeclareInt AstNodeType = iota
	ProgramRoot
	ExprAdd
	ExprSub
	ExprMul
	ExprDiv
	LiteralInt
)

var AST_NODE_DESC = map[AstNodeType]string{
	DeclareInt:  "DeclareInt",
	ProgramRoot: "ProgramRoot",
	ExprAdd:     "ExprAdd",
	ExprSub:     "ExprSub",
	ExprMul:     "ExprMul",
	ExprDiv:     "ExprDiv",
	LiteralInt:  "LiteralInt",
}

type AstNode struct {
	Type     AstNodeType
	Value    string
	Children []*AstNode
}

func (t *AstNode) ToString(step int) string {
	// 遍历树展示, 不同层级不同\t缩进
	str := fmt.Sprintf("%s%s v:%s", strings.Repeat("\t", step), AST_NODE_DESC[t.Type], t.Value)
	for _, child := range t.Children {
		str += "\n" + child.ToString(step+1)
	}

	return str
}
